package main

import . "curses"
import "os"
import "fmt"
import "strings"

var text =
`def inc(x) = x + 1
##
println( "inc(16) = ", inc(16), Char::nl )
##
another line
`

func main() {
    x := 10
    y := 10

    startGoCurses()
    defer stopGoCurses()
    
    Init_pair(1, COLOR_RED, COLOR_BLACK)
    Init_pair(2, COLOR_GREEN, 7)
    Init_pair(3, COLOR_RED, COLOR_WHITE )
    
    loop(x, y);
}

func startGoCurses() {
    Initscr();
    if Stdwin == nil {
        stopGoCurses()
        os.Exit(1)
    }
    
    Noecho()
    
    // Curs_set(CURS_HIDE)
    
    Stdwin.Keypad(true)
    EnableMouse()
    
    if err := Start_color(); err != nil {
        fmt.Printf("%s\n", err.String())
        stopGoCurses()
        os.Exit(1)
    }
    InitColor( 7, 500, 500, 0 )
}

func stopGoCurses() {
    Endwin()
}

type mark interface {
    line() int
}

type mint int

func (m mint) line() int { return int(m) }

type marks []mark

func (pm *marks) push( line int ) {
    m := *pm
    l := len(m)
    if l == cap(*pm) {
        m2 := make(marks, cap(*pm) * 2 + 1)
        copy(m2, m)
        m = m2    
    }
    m = m[0:l+1]
    m[l] = mint(line)
    *pm = m
}

func loop(x, y int) {
    x, y = 1, 0
    Stdwin.Clear()
    lines := strings.Split( text, "\n", -1 )
    for _, line := range lines {
        y += 1
        x = 1
        attributes := int(Color_pair(2)) 
        if y & 1 == 0 { Stdwin.SetAttributes( attributes ) } else { Stdwin.RemoveAttributes( attributes ) } 
        for _, ch := range line {
            Stdwin.Addch( x, y, int32(ch), Color_pair(0) )
            x += 1
        }
    }
    x, y = 1, 1
    Stdwin.RemoveAttributes( int(Color_pair(2)))
    var marked marks
    for {
        displayFrame( marked )
        Stdwin.Move( x, y )
        Stdwin.Refresh()
	    inp := Stdwin.Getch()
	    if inp == 'q' { break }
	    if inp == 'm' { marked.push(y) }
	    // if inp == '!' { Init_pair(2, COLOR_RED, COLOR_BLUE); Stdwin.Addch( 0, 20, int32(MY_ULC), Color_pair(0) ) }
	    if inp == KEY_LEFT { if x == 1 {} else x = x - 1 }
	    if inp == KEY_RIGHT { x = x + 1 }
	    if inp == KEY_UP { if y == 1 {} else y = y - 1 }
	    if inp == KEY_DOWN { y = y + 1 }
	    if inp == KEY_MOUSE { // 0631 /* KEY_MOUSE */ {
	        mx, my, mbuttons := MouseEvent()
	        _ = mbuttons
	        Stdwin.SetAttributes( int(Color_pair(1)) )
	        Stdwin.Addstr( 10, 1, "mx = %v, my = %v", 0, mx, my )
	        Stdwin.RemoveAttributes( int(Color_pair(1)) )
	        x, y = mx, my
	    }
	    //    Stdwin.Addstr( 1, 1, "x = %v, y = %v", 0, x, y )
	    ch := '?' // lines[y][x]
	    i, j := x - 1, y - 1
	    if 0 <= j && j < len(lines) {
	        if 0 <= i && i < len(lines[j]) { ch = int(lines[j][i]) }
    }
    Stdwin.Addch( 1, 1, int32(ch), Color_pair(0) )
    i = 10
    // for _, ch := range acs_items { Stdwin.Addch( i, 0, int32(ch), Color_pair(0) ); i += 1 }
    // Stdwin.Addch( 10, 0, ACS_LTEE, Color_pair(0) )
    // for i := 11; i < 40; i += 1 { Stdwin.Addch( i, 0, ACS_HLINE, Color_pair(0) ) }
    // Stdwin.Addch( 40, 0, ACS_RTEE, Color_pair(0) )

    // _ = ch; Stdwin.Addch( 0, 0, int32(ACS_PI), Color_pair(0) )
    }
}

func displayFrame( marked []mark ) {
    cols := *Cols
    rows := *Rows
  //
    for i := 0; i < cols; i += 1 { Stdwin.Addch( i, 0, ACS_HLINE, Color_pair(0) ) }
    for i := 0; i < cols; i += 1 { Stdwin.Addch( i, rows - 1, ACS_HLINE, Color_pair(0) ) }
    for j := 0; j < rows; j += 1 { Stdwin.Addch( 0, j, ACS_VLINE, Color_pair(0) ) }    
    for j := 0; j < rows; j += 1 { Stdwin.Addch( cols - 1, j, ACS_VLINE, Color_pair(0) ) }
  //
	Stdwin.Addch( 0, 0, ACS_ULCORNER, Color_pair(0) )
	Stdwin.Addch( cols - 1, 0, ACS_URCORNER, Color_pair(0) )
	Stdwin.Addch( 0, rows - 1, ACS_LLCORNER, Color_pair(0) )
	Stdwin.Addch( cols - 1, rows - 1, ACS_LRCORNER, Color_pair(0) )
  //
    for _, m := range marked {
        Stdwin.Addch( 0, m.line(), '*', Color_pair(0) )
        Stdwin.SetAttributeRun( 1, m.line(), 10, 0, 3 )
    }
}

